/**
 * 由 宝硕(https://github.com/renbaoshuo) 修改自 https://github.com/tangkaichuan/gridea-search
 */

(function () {
	//获取url参数
	function getParam(url, param) {
		if (url.indexOf("?") > -1) {
			var urlSearch = url.split("?");
			var paramList = urlSearch[1].split("&");
			for (var i = paramList.length - 1; i >= 0; i--) {
				var temp = paramList[i].split("=");
				if (temp[0] === param) {
					return temp[1];
				}
			}
		} else {
			return "";
		}
	}

	//获取解码后的搜索词
	function getQueryPhrase() {
		if (window.location.href.indexOf("?") == -1) return "";
		var phrase = getParam(window.location.href, "q");
		var queryPhrase = decodeURIComponent(phrase.replace(/\+/g, " "));
		return queryPhrase;
	}

	//填充搜索输入框
	function fillSearchInput() {
		var searchForm = document.getElementById("gridea-search-form");
		var searchInput = searchForm.getElementsByTagName("input")[0];
		searchInput.value = getQueryPhrase();
	}

	//Ajax异步GET请求
	function ajax(obj) {
		var xhr = new XMLHttpRequest();
		xhr.open("get", obj.url, true);
		xhr.send(null);
		xhr.onreadystatechange = function () {
			//异步请求：响应状态为4，数据加载完毕
			if (xhr.readyState === 4) {
				if (xhr.status === 200) {
					obj.success(xhr.responseText);
				} else {
					obj.error(xhr.status);
				}
			}
		};
	}

	//模糊搜索 https://github.com/krisk/fuse
	function fuzzySearch(data, phrase) {
		var options = {
			includeMatches: true,
			ignoreLocation: true,
			keys: ["title", "content"],
		};
		var fuse = new Fuse(data, options);
		var fuzzyResult = fuse.search(phrase);
		return fuzzyResult;
	}

	//检查缓存是否最新
	function checkCache() {
		var caches = {};
		caches.infos = JSON.parse(localStorage.getItem("InfosCache"));
		caches.contents = JSON.parse(localStorage.getItem("ContentsCache"));
		if (caches.infos && caches.contents) {
			var cachedTime = caches.infos.utils.now.toString();
			var updateTime = document.getElementById("gridea-search-result").getAttribute("data-update");
			if (cachedTime === updateTime) {
				return caches;
			}
		}
		localStorage.removeItem("InfosCache");
		localStorage.removeItem("ContentsCache");
		return false;
	}

	//获取博客全文api
	function getContents(callback) {
		var caches = checkCache();
		if (caches) {
			callback(caches.contents);
		} else {
			ajax({
				url: "../api-content/index.html" + "?_=" + Date.now(),
				success: function (data) {
					callback(JSON.parse(data));
					localStorage.setItem("ContentsCache", data);
				},
			});
		}
	}

	//获取博客信息api
	function getInfos(callback) {
		var caches = checkCache();
		if (caches) {
			callback(caches.infos);
		} else {
			ajax({
				url: "../api-info/index.html" + "?_=" + Date.now(),
				success: function (data) {
					callback(JSON.parse(data));
					localStorage.setItem("InfosCache", data);
				},
			});
		}
	}

	//根据一段文本调用模糊搜索
	function searchBy(phrase, callback) {
		var result = "";
		var getFuzzyResult = function (data) {
			result = fuzzySearch(data.posts, phrase);
			callback(result);
		};
		//根据全文内容获取搜索结果
		getContents(getFuzzyResult);
	}

	//显示无搜索结果
	function showNoResult() {
		var resultDIV = document.getElementById("gridea-search-result");
		var noResult = resultDIV.getElementsByClassName("no-result")[0];
		noResult.style.display = "block";
		resultDIV.innerHTML = noResult.outerHTML;
	}

	//根据解码后的搜索词执行搜索
	function searchByPhrase(resultHandler) {
		var queryPhrase = getQueryPhrase();
		if (queryPhrase === "" || typeof queryPhrase === "undefined") {
			showNoResult();
		} else {
			searchBy(queryPhrase, resultHandler);
		}
	}

	//获取搜索结果列表模板的URL
	function getTemplateURL() {
		var scripts = document.getElementsByTagName("script");
		var templateURL = "";
		for (var i = 0; i < scripts.length; i++) {
			if (scripts[i].type === "text/ejs") {
				templateURL = scripts[i].src;
				return templateURL;
			}
		}
	}

	//渲染搜索结果列表ejs https://github.com/mde/ejs
	function renderResult(searchedInfos) {
		if (searchedInfos.posts.length > 0) {
			ajax({
				url: getTemplateURL(),
				success: function (data) {
					var resultDIV = document.getElementById("gridea-search-result");
					resultDIV.innerHTML = ejs.compile(data)(searchedInfos);
				},
			});
		} else {
			showNoResult();
		}
	}

	//搜索结果关键字高亮
	function keywordHighlight(searchedContent) {
		var searchedPostContent = searchedContent.item.content; //搜索结果内容预览
		var preview = "... ";
		for (var i = 0; i < searchedContent.matches.length; i++) {
			if (searchedContent.matches[i].key === "content") {
				//如果匹配到文章内容，截取关键字
				var indices = searchedContent.matches[i].indices[0];
				var beforeKeyword = searchedPostContent.substring(indices[0] - 20, indices[0]); //关键字前10字
				var keyword = searchedPostContent.substring(indices[0], indices[1] + 1); //关键字
				var afterKeyword = searchedPostContent.substring(indices[1] + 1, indices[1] + 120); //关键字后70字
				preview = beforeKeyword + '<span class="searched-keyword">' + keyword + "</span>" + afterKeyword;
			} else {
				//没有匹配到文章内容，则是标题，直接截取前80字
				preview = searchedPostContent.substring(0, 80);
			}
		}
		return preview + " ...";
	}

	//循环匹配搜索到的内容与展示信息
	function getResult(infos, searchedContents) {
		var searchedInfos = JSON.parse(JSON.stringify(infos)); //对象深拷贝
		searchedInfos.posts = [];
		for (var i = 0; i < searchedContents.length; i++) {
			for (var j = 0; j < infos.posts.length; j++) {
				if (searchedContents[i].item.link === infos.posts[j].link) {
					infos.posts[j].searchedPreview = keywordHighlight(searchedContents[i]); // 预览关键字高亮
					infos.posts[j].content = searchedContents[i].item.content; // content注入
					searchedInfos.posts.push(infos.posts[j]); // push到所需结果中
				}
			}
		}
		return searchedInfos;
	}

	//主方法
	function grideaSearch() {
		//搜索结果回调
		var resultHandler = function (searchedContents) {
			getInfos(function (infos) {
				// console.log(infos);
				// console.log(searchedContents);
				var searchedInfos = getResult(infos, searchedContents);
				renderResult(searchedInfos);
			});
		};
		searchByPhrase(resultHandler);
	}

	//页面加载完执行
	window.onload = function () {
		fillSearchInput();
		grideaSearch();
	};
})();
